/** 
Copyright (c) 2010, Sheikh Abdul Wahid Ahmed
Details @ http://extremecodeworld.codeplex.com/license
**/

using System;
using EXtremecode.Utils;
using System.Data;
using System.Data.SqlClient;
using EXtremecode.DataAccessLayer; 
using System.Collections;
using System.Text;
using EXtremecode.Common;
using System.Data.Common;
using System.Text.RegularExpressions;
using EXtremecode.DataAccessLayer.Services;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;

namespace EXtremecode.DataAccessLayer
{
	/// <summary>
	/// Summary description for SQLServerDataAccessor.
	/// </summary>
	public class ServiceDataAccessor:DataAccessor
	{
        DataAccessor serverAccessor = null;
        private IDBService serviceClient = null;

        public IDBService ServiceClient
        {
            get { return serviceClient; }
           
        }
        public override string GetEnclosedDbObject(string dbObjectName)
        {
            return serverAccessor.GetEnclosedDbObject(dbObjectName);
        }
        private string mappedAccessorName = string.Empty;

        public string MappedAccessorName
        {
            get { return mappedAccessorName; }
           
        }
        private string endpoint = string.Empty;

        public string Endpoint
        {
            get { return endpoint; }
            set { endpoint = value; }
        }

        #region SYSTEM QUERIES
		internal override string QUERY_Table 
		{ 
			get 
			{
				return	serverAccessor.QUERY_Table;
			}
		}
        internal override string QUERY_View 
		{
			get 
			{
				return serverAccessor.QUERY_View;
			}
		}
		internal override string QUERY_TableColumn 
		{
			get 
			{
                return serverAccessor.QUERY_TableColumn;
            }
		}
		#endregion


        protected override DataTable GetRelationInfo()
        {
            return null;
        }

        public override string DBNow
        {
            get { return serverAccessor.DBNow; }
        }


        public ServiceDataAccessor(string sAccessorName, string sConnectionURL)
            : base(sAccessorName, sConnectionURL)
		{
            string serverType = string.Empty;
            serverType = StringProcessor.GetValueFromConnetionString(sConnectionURL, "Server Type");
            
            if (serverType.Trim() == string.Empty)
            {
                throw new Exception(string.Format("[UE] {0}, server type should be defined for mapping queries on server", sAccessorName));
            }
            Type typeDataAccessor = Type.GetType(string.Format("EXtremecode.DataAccessLayer.{0}DataAccessor", serverType));
			serverAccessor =Activator.CreateInstance(typeDataAccessor,new object[3]{sAccessorName,sConnectionURL,false}) as DataAccessor;



            //Mapped Accessor 
            mappedAccessorName = StringProcessor.GetValueFromConnetionString(sConnectionURL, "Mapped Accessor");
            if (mappedAccessorName.Trim() == string.Empty)
            {
                throw new Exception(string.Format("[UE] mapped accessor should be defined for mapping queries on server"));
            }

            //Endpoint
            endpoint = StringProcessor.GetValueFromConnetionString(sConnectionURL, "Endpoint");
            if (endpoint.Trim() == string.Empty)
            {
                throw new Exception(string.Format("[UE] service uri should be defined to connect to server"));
            }







            //Open Channel for specified endpoint.
            EndpointAddress endPointAddress = new EndpointAddress(endpoint);
            ContractDescription desc = ContractDescription.GetContract(typeof(IDBService));
            Binding binding = new WSHttpBinding();
            ServiceEndpoint endPoint = new ServiceEndpoint(desc, binding, endPointAddress);
            ChannelFactory<IDBService> channelFactory = new ChannelFactory<IDBService>(endPoint);
            serviceClient = channelFactory.CreateChannel();
            ((IChannel)serviceClient).Faulted += new EventHandler(ServiceConnection_Faulted);

            
        }

        void ServiceConnection_Faulted(object sender, EventArgs e)
        {

        }
		

		

		internal override string AdjustUDType4BinaryField(int intTypeCode,string strUDType)
		{
            return serverAccessor.AdjustUDType4BinaryField(intTypeCode, strUDType);
		}
		
		
		
		public override string GetParameterName(string paramName)
		{
            return serverAccessor.GetParameterName(paramName);
		}
		public override IDbCommand CreateCommand()
		{
			
			return new ServiceCommand(this); 
		}

        internal override IDbDataAdapter CreateDataAdapter()
		{
			return new ServiceDataAdapter(this);
		}

		public override IDataParameter GetParameter(string name,string type)
		{
            IDataParameter serverParam = serverAccessor.GetParameter(name, type);
            ServiceParameter param = new ServiceParameter(name,serverParam.DbType);
            return param;
		}
		

		
		protected override IDbConnection  CreateConnection()
		{
            ServiceConnection conn = new ServiceConnection(this);
			return conn;

		}

        

        internal override string GeneratePagingQuery(string selectQuery, string sortedBy, bool isSortingTypeAscending, int pageNumber, int pageSize, long? totalRecords)
        {
            return serverAccessor.GeneratePagingQuery(selectQuery, sortedBy, isSortingTypeAscending, pageNumber, pageSize, totalRecords); 
		}

        public override System.Collections.Generic.IEnumerable<IDbCommand> GetInternalCommands(IDbCommand mainCommand)
        {
            return serverAccessor.GetInternalCommands(mainCommand);
        }
	}
}
